package service

import (
	"errors"
	"hmsDemo/hms.service/handler"

	"gitee.com/tgodfather/go-plugins/serviceparam"

	validation "github.com/go-ozzo/ozzo-validation/v4"
	"github.com/micro/go-micro/v2/broker"
	"github.com/micro/go-micro/v2/config/cmd"
	"github.com/micro/go-micro/v2/registry"

	//"fmt"
	//"os"
	"strings"
	//"github.com/micro/go-micro/v2/util/log"

	grpc "gitee.com/tgodfather/go-plugins/client/grpc"
	//hms "image/common/hms"
	//"github.com/micro/cli/v2"
	"hmsDemo/hms.service/config"

	"github.com/micro/go-micro/v2"

	//"hms/hms.service/handler"
	//"hms/hms.service/subscriber"
	//"hms/hms.service/taskflow"

	log "gitee.com/tgodfather/misc/logger"

	"go.uber.org/zap"
)

func checkImageServiceCfg(cfg *config.ServiceConfig) ([]micro.Option, error) {
	var err error
	var serviceOpts []micro.Option
	funcOpt := func(opt ...micro.Option) {
		serviceOpts = append(serviceOpts, opt...)
	}
	//registry param
	if err = checkRegistryParam(cfg, funcOpt); nil != err {
		log.Fatal("config check Error", zap.Error(err))
		return serviceOpts, err
	}
	//client param
	if err = checkClientParam(cfg, funcOpt); nil != err {
		log.Fatal("config check Error", zap.Error(err))
		return serviceOpts, err
	}
	//server param
	if err = checkServerParam(cfg, funcOpt); nil != err {
		log.Fatal("config check Error", zap.Error(err))
		return serviceOpts, err
	}
	//broker param
	if err = checkBrokerParam(cfg, funcOpt); nil != err {
		log.Fatal("config check Error", zap.Error(err))
		return serviceOpts, err
	}
	//本地服务参数
	if err = checkLocalServiceParam(cfg, funcOpt); nil != err {
		log.Fatal("config check Error", zap.Error(err))
		return serviceOpts, err
	}

	return serviceOpts, nil
}

type FuncOpt func(opt ...micro.Option)

func InitTracer(cfg *config.ServiceConfig) {
	//oap服务 的IP
	oapServer := ""
	if value, bExist := cfg.GetParam("oap.server"); bExist {
		oapServer = value
	}

	//oap 实例的服务名，默认与服务名相同
	serviceName := cfg.ServiceName
	if value, bExist := cfg.GetParam("oap.serviceName"); bExist {
		serviceName = value
	}

	//oap 实例的ID
	instanceId := ""
	if value, bExist := cfg.GetParam("oap.instance.id"); bExist {
		instanceId = value
	}

	if 0 < len(oapServer) {
		log.Info("create tracer", zap.String("oap.server", oapServer),
			zap.String("oap.serviceName", serviceName),
			zap.String("oap.instance.id", instanceId),
		)
		//wrapperTrace.TraceBoot(oapServer, serviceName, instanceId)
	}

}

func checkRegistryParam(cfg *config.ServiceConfig, fo FuncOpt) error {
	//broker
	var err error
	err = validation.Validate(cfg.RegistryAddress, validation.Length(5, 128))
	if nil == err && strings.Contains(cfg.RegistryAddress, "$") {
		err = errors.New("RegistryAddress Not prepare")
	}
	if nil != err {
		log.Error("checkBrokerParam error", zap.Error(err))
		//该参数错误 ， 影响正常启动
		return err
	}

	//服务注册的参数
	regParam := map[string]string{
		"regGroup": "hms", //注册的 group Name
		//"regNS": "cde", //注册的 namespace
		//"regCluster": "",   //注册的 cluster Name
		"watchGroup": "hms", //监听的group，默认为regGroup
		//"watchCluster":  "hms",  //监听的group，regCluster
	}
	f := func(key, value string) bool {
		//只支持 a.b 的参数名， 不支持 a.b.c
		arrayKey := strings.Split(key, ".")
		if 2 == len(arrayKey) {

			if "registry" == arrayKey[0] {
				paramName := arrayKey[1]
				regParam[paramName] = value
				log.Info("Config registry Param",
					zap.String("key", paramName),
					zap.String("value", value))
			}
		}
		return false // 返回false 表示 继续
	}
	cfg.WalkParams(f)

	opt := micro.Registry(cmd.DefaultRegistries[cfg.RegistryType](
		registry.Addrs(cfg.RegistryAddress),
		serviceparam.ContextParam(regParam)))
	fo(opt)
	return nil
}

func checkClientParam(cfg *config.ServiceConfig, fo FuncOpt) error {
	opt := micro.Client(grpc.NewClient())
	fo(opt)
	return nil
}

func checkServerParam(cfg *config.ServiceConfig, fo FuncOpt) error {
	return nil
}

func checkBrokerParam(cfg *config.ServiceConfig, fo FuncOpt) error {
	//broker
	var err error
	err = validation.Validate(cfg.BrokerAddress, validation.Length(5, 128))
	if nil == err && strings.Contains(cfg.BrokerAddress, "$") {
		err = errors.New("ServerAddress Not prepare")
	}

	if nil != err {
		opt := micro.Broker(cmd.DefaultBrokers[cfg.BrokerType](broker.Addrs(cfg.BrokerAddress)))
		fo(opt)
	} else {
		log.Error("checkBrokerParam error", zap.Error(err))
		//该参数错误 ， 不影响正常启动
	}
	return nil
}

//本地服务参数
func checkLocalServiceParam(cfg *config.ServiceConfig, fo FuncOpt) error {
	var err error
	err = validation.Validate(cfg.ServerAddress, validation.Length(1, 128))
	if nil == err && strings.Contains(cfg.ServerAddress, "$") {
		err = errors.New("ServerAddress Not prepare")
	}
	if nil == err {
		opt := micro.Address(cfg.ServerAddress)
		fo(opt)
	} else {
		log.Error("checkLocalServiceParam error", zap.Error(err))
		//该参数错误 ， 直接返回错误，终止初始化
		return err
	}
	return nil
}

func CrawlService(cfg *config.ServiceConfig, ver string) {
	//servceId := strings.ToLower(cfg.ID)
	serviceName := strings.ToLower(cfg.ServiceName)
	log.Info("Init", zap.String("serviceType", cfg.ServiceType),
		zap.String("serviceName", cfg.ServiceName),
		zap.String("version", ver))
	//检查配置,生成启动参数
	serviceOpts, err := checkImageServiceCfg(cfg)
	if nil != err {
		log.Fatal("config check Error", zap.Error(err))
		return
	} else {
		log.Info("config check valid", zap.Reflect("configs", cfg))
	}

	//初始化Tracer如果有配置
	InitTracer(cfg)

	//基础参数
	serviceOpts = append(serviceOpts,
		micro.Name(serviceName),
		micro.Version(ver),
	)

	service := micro.NewService(serviceOpts...)

	//设置trace wrapper
	//service.Server().Init(server.WrapHandler(wrapperTrace.NewHandlerWrapper(nil)))
	service.Server().Init()
	log.Info("service init ...")
	// Initialise service
	service.Init()
	//service.Init(micro.Action(func(c *cli.Context) error{
	//	if c.Bool("version") {
	//		//runClient(service)
	//		fmt.Println(VER_STRING)
	//		os.Exit(0)
	//	}
	//	//fmt.Println("check version flag", c.Bool("version"))
	//	return nil
	//}))
	log.Info("service init Success")
	//log.Error("Check serivce Client", zap.Reflect("c", service.Client()), zap.Bool("b", bClient))

	// tf, tfErr := taskflow.NewTaskFlow(cfg.WorkCenterConfig, cfg.TaskCenterConfig, service.Client())
	// if nil != tfErr {
	// 	log.Fatal("Crate TaskFlow Fail", zap.Error(tfErr))
	// 	return
	// } else {
	// 	log.Info("Create TaskFlow Success, start tf ")
	// }
	// tf.Start()
	//注册Handler
	log.Info("start init handler")
	// handler.GetHandlerCenter().Init(service, cfg, tf)
	handler.GetHandlerCenter().Init(service, cfg)
	log.Info("start init handler ok")
	//注册Subscriber

	log.Info("start to run service")
	// Run service
	if err := service.Run(); err != nil {
		log.Fatal("Service Run Fail", zap.Error(err))
	}
	log.Info("service already stop")
	//stop

	// tf.Stop()
	log.Info("taskflow stop ok")
}
